package com.gec.anan.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gec.anan.common.constant.MqConst;
import com.gec.anan.common.constant.SystemConstant;
import com.gec.anan.common.execption.AnanException;
import com.gec.anan.common.result.ResultCodeEnum;
import com.gec.anan.common.service.RabbitService;
import com.gec.anan.driver.client.DriverAccountFeignClient;
import com.gec.anan.model.entity.payment.PaymentInfo;
import com.gec.anan.model.enums.TradeType;
import com.gec.anan.model.form.driver.TransferForm;
import com.gec.anan.model.form.payment.PaymentInfoForm;
import com.gec.anan.model.form.payment.ProfitsharingForm;
import com.gec.anan.model.vo.order.OrderProfitsharingVo;
import com.gec.anan.model.vo.order.OrderRewardVo;
import com.gec.anan.model.vo.payment.WxPrepayVo;
import com.gec.anan.order.client.OrderInfoFeignClient;
import com.gec.anan.payment.mapper.PaymentInfoMapper;
import com.gec.anan.payment.service.WxPayService;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.payments.model.Transaction;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
@Slf4j
public class WxPayServiceImpl implements WxPayService {


    @Autowired
    PaymentInfoMapper paymentInfoMapper;
    @Autowired
    RSAAutoCertificateConfig rsaAutoCertificateConfig;
//    @Autowired
//    WxPayV3Properties wxPayV3Properties;
    @Autowired
    OrderInfoFeignClient orderInfoFeignClient;
    @Autowired
    DriverAccountFeignClient driverAccountFeignClient;

    @Autowired
    private RabbitService rabbitService;

    @GlobalTransactional
    @Override
    public void handleOrder(String orderNo) {
        //1.更改订单支付状态
        orderInfoFeignClient.updateOrderPayStatus(orderNo);

        //2.处理系统奖励，打入司机账户
        OrderRewardVo orderRewardVo = orderInfoFeignClient.getOrderRewardFee(orderNo).getData();
        if(null != orderRewardVo.getRewardFee() && orderRewardVo.getRewardFee().doubleValue() > 0) {
            TransferForm transferForm = new TransferForm();
            transferForm.setTradeNo(orderNo);
            transferForm.setTradeType(TradeType.REWARD.getType());
            transferForm.setContent(TradeType.REWARD.getContent());
            transferForm.setAmount(orderRewardVo.getRewardFee());
            transferForm.setDriverId(orderRewardVo.getDriverId());
            driverAccountFeignClient.transfer(transferForm);
        }
        //3.TODO分账
        //分账处理
        OrderProfitsharingVo orderProfitsharingVo = orderInfoFeignClient.getOrderProfitsharing(orderRewardVo.getOrderId()).getData();
        //封装分账参数对象
        ProfitsharingForm profitsharingForm = new ProfitsharingForm();
        profitsharingForm.setOrderNo(orderNo);
        profitsharingForm.setAmount(orderProfitsharingVo.getDriverIncome());
        profitsharingForm.setDriverId(orderRewardVo.getDriverId());
        //分账有延迟，支付成功后最少2分钟执行分账申请
        rabbitService.sendDelayMessage(MqConst.EXCHANGE_PROFITSHARING, MqConst.ROUTING_PROFITSHARING, JSON.toJSONString(profitsharingForm), SystemConstant.PROFITSHARING_DELAY_TIME);
    }

    @Override
    public WxPrepayVo createWxPayment(PaymentInfoForm paymentInfoForm) {
        System.out.println(paymentInfoForm.getOrderNo());
        try {
            PaymentInfo paymentInfo = paymentInfoMapper.selectOne(new LambdaQueryWrapper<PaymentInfo>()
                    .eq(PaymentInfo::getOrderNo,paymentInfoForm.getOrderNo()));
            if (paymentInfo == null) {
                paymentInfo = new PaymentInfo();
                BeanUtils.copyProperties(paymentInfoForm,paymentInfo);
                paymentInfo.setPaymentStatus(0);
                paymentInfoMapper.insert(paymentInfo);
            }
//            //构建serivce
//            JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(rsaAutoCertificateConfig).build();
//
//            // request.setXxx(val)设置所需参数，具体参数可见Request定义
//            PrepayRequest request = new PrepayRequest();
//            Amount amount = new Amount();
//            amount.setTotal(paymentInfoForm.getAmount().multiply(new BigDecimal(100)).intValue());
//            request.setAmount(amount);
//            request.setAppid(wxPayV3Properties.getAppid());
//            request.setMchid(wxPayV3Properties.getMerchantId());
//            //string[1,127]
//            String description = paymentInfo.getContent();
//            if (description.length() >127) {
//                description = description.substring(0,127);
//            }
//            request.setDescription(paymentInfo.getContent());
//            request.setNotifyUrl(wxPayV3Properties.getNotifyUrl());
//            request.setOutTradeNo(paymentInfo.getOrderNo());
//
//            //获取用户信息
//            Payer payer = new Payer();
//            payer.setOpenid(paymentInfoForm.getCustomerOpenId());
//            request.setPayer(payer);
//            //是否指定分账，不指定不能分账
//            SettleInfo settleInfo = new SettleInfo();
//            settleInfo.setProfitSharing(true);
//            request.setSettleInfo(settleInfo);
//
//            // 调用下单方法，得到应答
//            // response包含了调起支付所需的所有参数，可直接用于前端调起支付
//            PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
//            log.info("微信支付下单返回参数：{}", JSON.toJSONString(response));
            System.out.println(paymentInfo.getCustomerOpenId()+"是否存在");
            WxPrepayVo wxPrepayVo = new WxPrepayVo();
            wxPrepayVo.setPaySign("abc123i789");
            wxPrepayVo.setSignType("ALIPuhhhAY");
            System.out.println(wxPrepayVo);
            wxPrepayVo.setAppId(paymentInfo.getCustomerOpenId());
            wxPrepayVo.setNonceStr("");
            wxPrepayVo.setPackageVal("预支付成功");
            wxPrepayVo.setTimeStamp(String.valueOf(System.currentTimeMillis() / 1000));
            Transaction transaction = new Transaction();
            transaction.setOutTradeNo(paymentInfo.getOrderNo());
            transaction.setTransactionId(paymentInfo.getTransactionId());
            handlePayment(transaction);
//            BeanUtils.copyProperties(response, wxPrepayVo);
//            wxPrepayVo.setTimeStamp(response.getTimeStamp());

            return wxPrepayVo;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AnanException(ResultCodeEnum.WX_CREATE_ERROR);
        }
    }



//    @Transactional
//    @Override
//    public void wxnotify(HttpServletRequest request) {
//        //1.回调通知的验签与解密
//        //从request头信息获取参数
//        //HTTP 头 Wechatpay-Signature
//        // HTTP 头 Wechatpay-Nonce
//        //HTTP 头 Wechatpay-Timestamp
//        //HTTP 头 Wechatpay-Serial
//        //HTTP 头 Wechatpay-Signature-Type
//        //HTTP 请求体 body。切记使用原始报文，不要用 JSON 对象序列化后的字符串，避免验签的 body 和原文不一致。
//        String wechatPaySerial = request.getHeader("Wechatpay-Serial");
//        String nonce = request.getHeader("Wechatpay-Nonce");
//        String timestamp = request.getHeader("Wechatpay-Timestamp");
//        String signature = request.getHeader("Wechatpay-Signature");
//        //String requestBody = RequestUtils.readData(request);
//        log.info("wechatPaySerial：{}", wechatPaySerial);
//        log.info("nonce：{}", nonce);
//        log.info("timestamp：{}", timestamp);
//        log.info("signature：{}", signature);
//        //log.info("requestBody：{}", requestBody);
//
//        //2.构造 RequestParam
//        RequestParam requestParam = new RequestParam.Builder()
//                .serialNumber(wechatPaySerial)
//                .nonce(nonce)
//                .signature(signature)
//                .timestamp(timestamp)
//                //.body(requestBody)
//                .build();
//
//
//        //3.初始化 NotificationParser
//        NotificationParser parser = new NotificationParser(rsaAutoCertificateConfig);
//        //4.以支付通知回调为例，验签、解密并转换成 Transaction
//
//        Transaction transaction = parser.parse(requestParam, Transaction.class);
//        log.info("成功解析：{}", JSON.toJSONString(transaction));
//        if(null != transaction && transaction.getTradeState() == Transaction.TradeStateEnum.SUCCESS) {
//            //5.处理支付业务
//            this.handlePayment(transaction);
//        }
//    }

    @Override
    public Boolean queryPayStatus(String orderNo) {
        // 构建service
//        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(rsaAutoCertificateConfig).build();
//
//        QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
//        queryRequest.setMchid(wxPayV3Properties.getMerchantId());
//        queryRequest.setOutTradeNo(orderNo);

        try {
//            Transaction transaction = service.queryOrderByOutTradeNo(queryRequest);
//            log.info(JSON.toJSONString(transaction));
//            if(null != transaction && transaction.getTradeState() == Transaction.TradeStateEnum.SUCCESS) {
//                //更改订单状态
//                this.handlePayment(transaction);
//                return true;
//            }
            Transaction transaction = new Transaction();
            transaction.setOutTradeNo(orderNo);

            handlePayment(transaction);
            return true;
        } catch (ServiceException e) {
            // API返回失败, 例如ORDER_NOT_EXISTS
            System.out.printf("code=[%s], message=[%s]\n", e.getErrorCode(), e.getErrorMessage());
        }
        return false;
    }


    public void handlePayment(Transaction transaction) {
        PaymentInfo paymentInfo = paymentInfoMapper.selectOne(new LambdaQueryWrapper<PaymentInfo>().eq(PaymentInfo::getOrderNo, transaction.getOutTradeNo()));
        if (paymentInfo.getPaymentStatus() == 1) {
            return;
        }

        //更新支付信息
        paymentInfo.setPaymentStatus(1);
        paymentInfo.setOrderNo(transaction.getOutTradeNo());
        paymentInfo.setTransactionId(transaction.getTransactionId());
        paymentInfo.setCallbackTime(new Date());
        paymentInfo.setCallbackContent(JSON.toJSONString(transaction));
        paymentInfoMapper.updateById(paymentInfo);
        // 表示交易成功！

        // 后续更新订单状态！ 使用消息队列！
        rabbitService.sendMessage(MqConst.EXCHANGE_ORDER, MqConst.ROUTING_PAY_SUCCESS, paymentInfo.getOrderNo());
    }




}
